/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controlleur.reponseQuestionnaire;

import entities.questionnaire.TypeScenario;
import java.io.Serializable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.icefaces.application.PortableRenderer;
import org.icefaces.application.PushRenderer;
import org.jboss.weld.resolution.TypeSafeBeanResolver;

/**
 *
 * @author aurelien.emery
 */
@ManagedBean(name = "navigationQuestionController")
@SessionScoped
public class NavigationQuestionController implements ServletContextListener, Serializable {

    private String repertoireNav = "/pages/includes/navigation/";
    private String nomNav = "sansNavigation.xhtml";
    private ReponseQuestionnaireController reponseQuestionnaireController;
    // attribut specifique au chrono
    protected static ThreadPoolExecutor longRunningTaskThreadPool;
    private PortableRenderer renderer;
    private int decompte;
    /**
     * Cet attribut permet de desactiver le bouton precedent
     */
    private boolean precedentActif;
    /**
     * Cet attribut permet de desactiver le bouton suivant
     */
    private boolean suivantActif;

    /** Creates a new instance of NavigationQuestionController */
    public NavigationQuestionController() {
        PushRenderer push = new PushRenderer();
        push.addCurrentSession("this");
        renderer = push.getPortableRenderer();
        init();
    }

    public void init() {
        precedentActif = false;
        suivantActif = true;
        decompte = -1;
    }

    /**
     * Cette methode permet de definir quel est le bandeau de navigation adequat pour le questionnaire.
     * Elle permet aussi de faire le lien pour la navigation dans les questions.
     * @param typeScenario le scenario associe au questionnaire
     * @param ctrl le controller qui gere les reponses au questionnaire
     */
    public void setConfiguration(TypeScenario typeScenario, ReponseQuestionnaireController ctrl) {
        this.reponseQuestionnaireController = ctrl;

        if (typeScenario != null) {

            switch (typeScenario) {
                case TEMPSILLIMITE: {
                    nomNav = "navigationBase.xhtml";
                    break;
                }
                case TEMPSILLIMITESANSNAVIGATION: {
                    nomNav = "navigationUnique.xhtml";
                    break;

                }
                case TEMPSLIMITESANSNAVIGATION: {
                    longRunningTaskThreadPool =
                            new ThreadPoolExecutor(5, 15, 30, TimeUnit.SECONDS,
                            new LinkedBlockingQueue(20));
                    nomNav = "navigationChrono.xhtml";
                    break;
                }
                // ce cas sert pour la page d accueil et de cloture du questionnaire
                default: {
                    nomNav = "sansNavigation.xhtml";
                }
            }
        } else {
            nomNav = "sansNavigation.xhtml";
        }
        renderer.render("this");
        if (typeScenario == TypeScenario.TEMPSLIMITESANSNAVIGATION) {
            startTime();
        }
    }

    public void suivant(ActionEvent ae) {
        // par defaut, si on passe a la question suivante, la precedente existe
        precedentActif = true;
        changeQuestion(1);
        if (reponseQuestionnaireController.getNbQuestion() == reponseQuestionnaireController.getNumQuestion()) {
            suivantActif = false;
        }
        renderer.render("this");
        if (decompte != -1) {
            startTime();
        }
    }

    public void precedent(ActionEvent ae) {
        // par defaut, si on passe a la question precedente, la suivante existe
        suivantActif = true;
        changeQuestion(-1);
        if (reponseQuestionnaireController.getNumQuestion() == 1) {
            precedentActif = false;
        }
        renderer.render("this");
    }

    public String terminer() {
        //TODO faire la cloture et redirection
        String result = reponseQuestionnaireController.terminer();
        return result;
    }

    /**
     * Permet de changer la question courante.
     * Le parametre indique le sens de navigation dans la collection de question
     * @param questionSuivante 1 pour la question suivante, -1 pour la précédente
     */
    private void changeQuestion(int questionSuivante) {
        reponseQuestionnaireController.changeQuestion(questionSuivante);
    }

    /**
     * Cette methode renvoit le nom du fichier de bandeau a afficher, ainsi que son chemin relatif
     * @return le nom du fichier de bandeau définit par la configuration
     */
    public String getBandeau() {
        return repertoireNav + nomNav;
    }

    /**
     * methode de demarrage du chrono
     */
    public void startTime() {
        // ajouter le changement de question
        longRunningTaskThreadPool.execute(new LongOperationRunner());
    }

    /**
     * Cette classe permet de gerer le thread de temps, ainsi que le decompte et la mise a jour de l affichage
     */
    protected class LongOperationRunner implements Runnable {

        public LongOperationRunner() {
        }

        /**
         * Routine that takes time and updates percentage as it runs.
         */
        public void run() {
            int start = reponseQuestionnaireController.getQuestionnaire().getDureeQuestion();
            try {
                for (int i = start; i >= 0; i -= 1) {
                    decompte = i;
                    // pause d une seconde
                    Thread.sleep(1000);
                    // push des valeurs du bean dans la page (maj chrono)
                    renderer.render("this");
                }
                // bascule l affichage vers le bouton de question suivante
                reponseQuestionnaireController.setQuestionVisible(false);


            } catch (InterruptedException e) {
            }
        }
    }

    /**
     * Cette methode permet l affichage de la question, et de déclencher le début du temps
     *
     * @return
     */
    public String demarrer() {
        //TODO voir pour passer cette methode de action a actionListener
        //TODO ajouter gestion du bouton de transition
        startTime();
        return null;
    }

    public int getDecompte() {
        return decompte;
    }

    public void setDecompte(int decompte) {
        this.decompte = decompte;
    }

    public boolean isPrecedentActif() {
        return precedentActif;
    }

    public void setPrecedentActif(boolean precedentActif) {
        this.precedentActif = precedentActif;
    }

    public boolean isSuivantActif() {
        return suivantActif;
    }

    public void setSuivantActif(boolean suivantActif) {
        this.suivantActif = suivantActif;
    }

    @Override
    public void contextInitialized(ServletContextEvent sce) {
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        if (longRunningTaskThreadPool != null) {
            longRunningTaskThreadPool.shutdownNow();
        }
    }
}
